package com.jszc.lottery.common.datatest;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

public class CommuDic extends LinkedHashMap<String, Object> {

    /**
     * 是否获取合法字符串
     */
    public static boolean NEED_GET_LEGAL_STR = false;

    public CommuDic() {
    }

    /**
     * 是否为null或字符为空
     */
    public boolean isEON(String key) {
        return StrUtil.isTEpt(this.getObj(key));
    }

    //region 获取数据的相关操作

    /**
     * 获得制定类型值
     */
    public Object getObj(String key) {
        if (!containsKey(key)) return null;
        return this.get(key);
    }

    /**
     * 获得制定类型值
     */
    public <T extends Object> T getData(Class<T> cls, String key) {
        if (this.isEON(key)) return null;
        T t =  (T) CommonUtil.as(this.getObj(key),cls);
        if(t != null){
            return t;
        }
        if(this.getObj(key) == null){
            return  null;
        }
        return JsonUtil.jsonToObj(cls, this.getStr(key));
    }


    /**
     * 获得数组 泛型 目前支持 int string guid
     */
    public <T> List<T> getList(Class<T> cls, String key) {
        if (this.isEON(key)) return new ArrayList<T>();
        String valStr = this.getStr(key);
        if (!valStr.startsWith("[") || !valStr.endsWith("]")) {
            valStr = String.format("[%s]", valStr);
        }
        return JsonUtil.jsonToObjList(cls, valStr);
    }


    /**
     * 获得int型的数据 如果throwExIfNull为false为null返回0
     */
    public Integer getInt(String key) {
        return getInt(key, false);
    }

    /**
     * 获得int型的数据 如果throwExIfNull为false为null返回0
     */
    public Integer getInt(String key, boolean throwExIfNull) {
        Object valObj = getObj(key);
        if (valObj == null && throwExIfNull) throw new CommonException(String.format("不存在指定键值[%s]", key));
        if (valObj == null && !throwExIfNull) valObj = 0;
        return Integer.parseInt(valObj.toString());
    }


    /**
     * 获得int型的数据 不存在或空文本异常返回errorDef
     *
     * @return
     */
    public Integer getIntNoErr(String key) {
        return getIntNoErr(key, 0);
    }

    /**
     * 获得int型的数据 不存在或空文本异常返回errorDef
     *
     * @return
     */
    public Integer getIntNoErr(String key, Integer errorDef) {
        if (!containsKey(key) || getObj(key) == null) return errorDef;
        if (this.isEON(key)) return errorDef;
        try {
            return getInt(key);
        } catch (Exception ex) {
            return errorDef;
        }
    }

    public Long getLong(String key) {
        return Long.parseLong(getObj(key).toString());
    }

    /**
     * 获取长整形
     */
    public Long getLongNoErr(String key) {
        return getLongNoErr(key, new Long(0));
    }

    /**
     * 获取长整形
     */
    public Long getLongNoErr(String key, Long errorDef) {
        if (!containsKey(key) || getObj(key) == null) return errorDef;
        if (this.isEON(key)) return errorDef;
        try {
            return getLong(key);
        } catch (Exception ex) {
            return errorDef;
        }
    }

    public Float getFLT(String key) {
        return Float.parseFloat(getObj(key).toString());
    }

    public Float getFLTNoErr(String key) {
        return getFLTNoErr(key, new Float(0));
    }

    public Float getFLTNoErr(String key, Float errorDef) {
        if (!containsKey(key) || getObj(key) == null) return errorDef;
        if (this.isEON(key)) return errorDef;
        try {
            return getFLT(key);
        } catch (Exception ex) {
            return errorDef;
        }
    }

    public Double getDBL(String key) {
        return Double.parseDouble(getObj(key).toString());
    }

    public Double getDBLNoErr(String key) {
        return getDBLNoErr(key, new Double(0));
    }

    public Double getDBLNoErr(String key, Double errorDef) {
        if (!containsKey(key) || getObj(key) == null) return errorDef;
        if (this.isEON(key)) return errorDef;
        try {
            return getDBL(key);
        } catch (Exception ex) {
            return errorDef;
        }
    }

    public BigDecimal getDEC(String key) {
        return new BigDecimal(getObj(key).toString());
    }

    public BigDecimal getDECNoErr(String key) {
        return getDECNoErr(key, new BigDecimal(0));
    }

    public BigDecimal getDECNoErr(String key, BigDecimal errorDef) {
        if (!containsKey(key) || getObj(key) == null) return errorDef;
        if (this.isEON(key)) return errorDef;
        try {
            return getDEC(key);
        } catch (Exception ex) {
            return errorDef;
        }
    }

    /**
     * 获得DateTime型的数据
     */
    public Date getDateTime(String key) {
        return getDateTime(key, "yyyy-MM-dd HH:mm:ss");
    }
    /**
     * 获得DateTime型的Date部分
     */
    public  Date getShortDate(String key){
        return getDateTime(key, "yyyy-MM-dd");
    }

    /**
     * 获得DateTime型的数据
     */
    public Date getDateTime(String key, String dateFormat) {
        try {
            if (this.isEON(key)) return null;
            Date t =  (Date) CommonUtil.as(this.getObj(key),Date.class);
            if(t != null){
                return t;
            }
            DateFormat df = new SimpleDateFormat(dateFormat);
            Date date = df.parse(getObj(key).toString());
            return date;
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * 获得DateTime型的数据 异常或不存在返回指定默认值
     */
    public Date getDateTimeNoErr(String key, Date errorDef) {
        if (!containsKey(key) || getObj(key) == null) return errorDef;
        try {
            return getDateTime(key);
        } catch (Exception ex) {
            return errorDef;
        }
    }


    /**
     * 获得string型的数据 不存在或异常返回string.empty
     */
    public String getStr(String key) {
        try {
            if(isEON(key)) return StrUtil.emptyString;
            Object obj = this.get(key);
            String str = StrUtil.emptyString;
            if(ReflectionUtil.inheritFrom(obj.getClass(),String.class)){
                str =  StrUtil.espNull(obj);
            }
            else
            {
                str =  StrUtil.espNull(JsonUtil.objToJson(obj));
            }
            if(NEED_GET_LEGAL_STR){
                if(ValidateUtil.validateByPattern(str,"[\\<\\>]")){
                    throw new ShowInfoException("输入值存在非法字符");
                }
            }
            return str;
        } catch (Exception ex) {
            ex.printStackTrace();
            return "";
        }
    }


    /**
     * 获得bool型的数据 不存在或异常返回false
     */
    public Boolean getBool(String key) {
        return Boolean.parseBoolean(getStr(key));
    }

    public Boolean getBoolNoErr(String key) {
        return getBoolNoErr(key, null);
    }

    public Boolean getBoolNoErr(String key, Boolean errDef) {
        if (!this.containsKey(key)) return errDef;
        try {
            return getBool(key);
        } catch (Exception ex) {
            ex.printStackTrace();
            return errDef;
        }
    }

    public UUID getGuid(String key) {
        try {
            return this.containsKey(key) ? UUID.fromString(this.getStr(key)) : null;

        } catch (Exception ex) {
            return null;
        }
    }
    public <TEnum extends Enum> TEnum getEnum(Class<TEnum> cls, String key) {
        if (!containsKey(key)) return null;
        return EnumUtil.valueOf(cls,this.getInt(key,true));
    }


    /**
     * 根据枚举名获取枚举实例
     */
    public <TEnum extends Enum> TEnum getEnum(Class<TEnum> cls, String key, TEnum errDef) {
        if (!containsKey(key)) return errDef;
        try {
            return EnumUtil.valueOf(cls,this.getInt(key,true));
        } catch (Exception ex) {
            return errDef;
        }
    }
    //endregion

    /**
     * 合并字典
     */
    public void merge(CommuDic dic) {
        Set<String> keys = dic.keySet();
        for (String key : keys) {
            this.put(key, dic.get(key));
        }
    }
}